package view.main;

import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.File;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.WindowConstants;

import constants.GUIConstants;
import controller.CSController;



import view.items.GrenadePanel;
import view.items.LOSPanel;
import view.items.MovePanel;
import view.items.OptionsPanel;
import view.player.PlayerPanel;
import view.timeline.TimeJumperPanel;
import view.timeline.TimelineCommandPanel;
import view.timeline.TimelinePanel;
import view.world.ColorPanel;
import view.world.WorldPanel;

public class MainPanel extends JFrame implements MouseListener,
										KeyListener, WindowListener {

	private int selected;
	
	private FilePanel filePan;
	
	private ColorPanel colorPan;
	private MovePanel movePan;
	private LOSPanel losPan;
	private GrenadePanel grePan;
	
	private OptionsPanel optPan;
	
	private TimelinePanel timelinePan;
	private TimelineCommandPanel timelineCommandPan;
	private TimeJumperPanel timeJumpPan;
	
	private PlayerPanel[] playerPan;
	
	private WorldPanel worldPan;
	private JScrollPane worldScroll;
	
	private CSController controller;
	
	public MainPanel(File mapImage, File mapFile) {
		
		JPanel main = new JPanel();
		
		JPanel fileRow = new JPanel();
		JPanel itemRow = new JPanel();
		JPanel worldRow = new JPanel();
		JPanel timeRow = new JPanel();
		
		JPanel timeCol = new JPanel();
		JPanel playerCol = new JPanel();
		
		JPanel fakeCol = new JPanel();
		
		JScrollPane playerScroll;
		
		fileRow.setLayout(new BoxLayout(fileRow, BoxLayout.LINE_AXIS));
		itemRow.setLayout(new BoxLayout(itemRow, BoxLayout.LINE_AXIS));
		worldRow.setLayout(new BoxLayout(worldRow, BoxLayout.LINE_AXIS));
		timeRow.setLayout(new BoxLayout(timeRow, BoxLayout.LINE_AXIS));
		
		playerCol.setLayout(new BoxLayout(playerCol, BoxLayout.PAGE_AXIS));
		timeCol.setLayout(new BoxLayout(timeCol, BoxLayout.PAGE_AXIS));
		fakeCol.setLayout(new BoxLayout(fakeCol, BoxLayout.PAGE_AXIS));
		
		main.setLayout(new BoxLayout(main, BoxLayout.PAGE_AXIS));

		selected = 0;
		
		filePan = new FilePanel();
		movePan = new MovePanel();
		losPan = new LOSPanel();
		grePan = new GrenadePanel();
		optPan = new OptionsPanel();
		colorPan = new ColorPanel(this);
		timelinePan = new TimelinePanel();
		timelineCommandPan = new TimelineCommandPanel();
		playerPan = new PlayerPanel[5];
		worldPan = new WorldPanel(mapImage);
		timeJumpPan = new TimeJumperPanel();
		
		// CONTOLLER :
		controller = new CSController(this, mapFile);
		
		for (int i=0; i<5; i++)
			playerPan[i] = new PlayerPanel(i,controller.getWorld().getPlayer(i).getName());
		playerPan[0].setSelected(true);
		
		fileRow.add(filePan);
		fileRow.add(Box.createHorizontalGlue());
		
		itemRow.add(movePan);
		itemRow.add(losPan);
		itemRow.add(grePan);
		itemRow.add(optPan);
		itemRow.add(Box.createHorizontalGlue());
		itemRow.add(colorPan);
		
		for (int i=0; i<5; i++)
			playerCol.add(playerPan[i]);
		
		worldScroll = new JScrollPane(worldPan);
		playerScroll = new JScrollPane(playerCol);
		playerScroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		playerScroll.setMinimumSize(new Dimension(155,100));
		playerScroll.setMaximumSize(new Dimension(155,999999));
		
		worldRow.add(worldScroll);
		worldRow.add(playerScroll);
		
		timeCol.add(timelinePan);
		timeCol.add(timelineCommandPan);
		
		fakeCol.add(timeJumpPan);
		fakeCol.add(Box.createVerticalGlue());
		
		timeRow.setMaximumSize(new Dimension(999999,50)); // NECESSARY
		timeRow.add(timeCol);
		timeRow.add(fakeCol);
		
		main.add(fileRow);
		main.add(itemRow);
		main.add(worldRow);
		main.add(timeRow);
		
		this.setPreferredSize(new Dimension(640, 480));
		this.setContentPane(main);
		
		this.setTitle("StratTimer "+GUIConstants.VERSION);
		this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
		this.addWindowListener(this);
		
		// LINKS :
		
		for (int i=0; i<5; i++) {
			playerPan[i].attachListener(controller);
			playerPan[i].addMouseListener(this);
			playerPan[i].getNamefield().addKeyListener(this);
		}
		filePan.attachListener(controller);
		movePan.attachListener(controller);
		losPan.attachListener(controller);
		grePan.attachListener(controller);
		optPan.attachListener(controller);
		timelinePan.attachListener(controller);
		timelineCommandPan.attachListener(controller);
		worldPan.attachListener(controller);
		timeJumpPan.attachListener(controller);
		
		grePan.setEnabled(false);
		
		controller.stateChanged(null);
	}
	
	public void display() {
		this.pack();
		Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
		this.setLocation(screen.width/2-this.getWidth()/2, screen.height/2-this.getHeight()/2);
		// Initially center the map :
		worldScroll.getVerticalScrollBar().setValue(worldPan.getHeight()/2
				-worldScroll.getVerticalScrollBar().getHeight()/2);
		worldScroll.getHorizontalScrollBar().setValue(worldPan.getWidth()/2
				-worldScroll.getHorizontalScrollBar().getWidth()/2);
		this.setVisible(true);
	}

	@Override
	public void setEnabled(boolean enabled) {
		filePan.setEnabled(enabled);
		movePan.setEnabled(enabled);
		losPan.setEnabled(enabled);
		grePan.setEnabled(enabled);
		optPan.setEnabled(enabled);
	}
	
	public int getSelected() {
		return selected;
	}
	
	public CSController getController() {
		return controller;
	}

	public FilePanel getFilePan() {
		return filePan;
	}

	public GrenadePanel getGrePan() {
		return grePan;
	}

	public LOSPanel getLosPan() {
		return losPan;
	}

	public OptionsPanel getOptionsPan() {
		return optPan;
	}
	
	public MovePanel getMovePan() {
		return movePan;
	}

	public PlayerPanel[] getPlayerPan() {
		return playerPan;
	}

	public TimeJumperPanel getTimeJumpPan() {
		return timeJumpPan;
	}

	public TimelineCommandPanel getTimelineCommandPan() {
		return timelineCommandPan;
	}

	public TimelinePanel getTimelinePan() {
		return timelinePan;
	}

	public WorldPanel getWorldPan() {
		return worldPan;
	}

	public void setAddingMove() {
		movePan.setAddingMove();
		grePan.setIdle();
		losPan.setIdle();
	}
	
	public void setInsertingMove() {
		movePan.setInsertingMove();
		grePan.setIdle();
		losPan.setIdle();
	}
	
	public void setDeletingMove() {
		movePan.setDeletingMove();
		grePan.setIdle();
		losPan.setIdle();
	}
	
	public void setAddingGre() {
		movePan.setIdle();
		grePan.setAddingGre();
		losPan.setIdle();
	}
	
	public void setDeletingGre() {
		movePan.setIdle();
		grePan.setDeletingGre();
		losPan.setIdle();
	}
	
	public void setAddingLOS() {
		movePan.setIdle();
		grePan.setIdle();
		losPan.setAddingLOS();
	}
	
	public void setDeletingLOS() {
		movePan.setIdle();
		grePan.setIdle();
		losPan.setDeletingLOS();
	}
	
	public void setIdle() {
		movePan.setIdle();
		grePan.setIdle();
		losPan.setIdle();
	}
	
	public void mouseClicked(MouseEvent e) {
		PlayerPanel pan = (PlayerPanel)e.getSource();
		
		playerPan[selected].setSelected(false);
		selected = pan.getId();
		pan.setSelected(true);
		
		worldPan.setSelected(null);
		
		controller.notifySelectedChange();
	}

	public void mouseEntered(MouseEvent arg0) {}
	public void mouseExited(MouseEvent arg0) {}
	public void mousePressed(MouseEvent arg0) {}
	public void mouseReleased(MouseEvent arg0) {}

	public void keyPressed(KeyEvent arg0) {}

	public void keyReleased(KeyEvent arg0) {
		controller.notifyNameChange();
	}

	public void keyTyped(KeyEvent arg0) {}

	public void windowActivated(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	public void windowClosed(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	public void windowClosing(WindowEvent arg0) {
		controller.notifyDeath();
		this.dispose();
	}

	public void windowDeactivated(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	public void windowDeiconified(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	public void windowIconified(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	public void windowOpened(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}
}
